﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Xml;
using System.Xml.Linq;
using System.IO;
using System.ComponentModel;

namespace CronCommon
{
    #region 命令参数解析类 CmdParameter    
    /// <summary>
    /// 命令参数解析
    /// </summary>
    public class CmdParameter
    {
        //发送历史数据
        public bool SendHistoryRecord { get; }
        public string HistoryRedordId { get; }

        //发送测试邮件
        public bool SendTestMail { get; }
        public string testToAddress { get; }

        public bool NoSendMail { get; } //不发邮件

        public bool CmdParameterCheck { get; } //参数检查通过


        public CmdParameter()
        {
            SendHistoryRecord = false;
            SendTestMail = false;
            NoSendMail = false;
            CmdParameterCheck = true;

        }

  
        /// <summary>
        /// 分解传递的参数
        /// </summary>
        /// <param name="cmdname"> 任务ID SN</param>
        /// <param name="vs"> 各种参数,字串数组</param>
        public CmdParameter(string cmdname, string[] vs) : this()
        {
            if (vs.Length <= 0)
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine("命令格式:");
                sb.AppendLine($"{cmdname} 任务ID -H 历史版本ID -T testToAddress -nomail");
                sb.AppendLine("任务ID          ;必要参数,不可缺");
                sb.AppendLine("-h 历史版本ID   ;发送以发送或失败的邮件");
                sb.AppendLine("-t 测试邮件地址 ;发送测试邮件");
                sb.AppendLine("-NoMail         ;不发邮件");

                Console.WriteLine(sb.ToString());
                CmdParameterCheck = false;
                return;
            }

            for (int i = 1; i < vs.Length; i++)
            {
                switch (vs[i].ToUpper())
                {
                    case "-H":
                        {
                            if (i == vs.Length - 1)
                            {
                                Console.WriteLine("没有输入历史版本参数,请注意.");
                                CmdParameterCheck = false;
                                return;
                            }

                            SendHistoryRecord = true;
                            if (!System.Text.RegularExpressions.Regex.IsMatch(vs[i + 1], "^[0-9]*$"))
                            {
                                Console.WriteLine("输入历史的参数有误,参数ID 为纯数字,请注意.");
                                CmdParameterCheck = false;
                                return;
                            }

                            HistoryRedordId = vs[i + 1];
                            break;
                        }
                    case "-T":
                        {
                            if (i == vs.Length - 1)
                            {
                                Console.WriteLine("没有输入测试邮件地址参数,请注意.");
                                CmdParameterCheck = false;
                                return;
                            }

                            SendTestMail = true;

                            testToAddress = vs[i + 1];
                            break;
                        }
                    case "-NOMAIL":
                        {
                            NoSendMail = true;
                            break;
                        }
                }

            }

        }

    }
    #endregion

    public class CronStruct
    {
        public string SN;
        public string CronName;
        public string MailTO;
        public string MailCC;
        public string MailBCC;
        public string MailSubject;
        public string MailBody;
        public string 执行命令;
        public string 附件文件名;
        public string 附件格式;
        public string 文件名后缀;
        public bool 邮件发送失败重试;
        public int 重试间隔分钟;
        public int 失败重试次数;
        public bool 附件HTML内容;
        public string 数据栏位格式化;
        public int 发邮件分组类型;//0 常规发一封邮件 1 按单身MailTo栏位发送一封邮件 2.按单身MailTo栏位按邮件地址分组发送邮件
        public bool 发送钉钉消息;
        public string 钉钉消息地址;
        public string attachMentFilename;

        public CmdParameter cmd;

        public MailArray mr;

        public bool 是否发送邮件 = false;

        public CronStruct()
        {
            this.发邮件分组类型 = 0;
        }

        public void InitMailData(SqlConnection conn)
        {
            if (cmd.SendHistoryRecord == true)
            {
                this.attachMentFilename = DbConn.GetCronHistoryRecord(conn, this.SN, cmd.HistoryRedordId);
                this.是否发送邮件 = true;
                Log.Writter(string.Format("历史记录附件名 {0}", attachMentFilename));
                return;
            }

            if (DbConn.CheckAttachmentData(conn, this.SN))
            {
                DataSet ds = DbConn.GetAttachmentData(conn, this.SN, true);
                if (ds == null)
                {
                    Log.Writter("没有附件数据源");
                    return;
                }

                bool isTableRecord = false;
                for (int i = 0; i < ds.Tables.Count; i++)
                {
                    if (ds.Tables[i].Rows.Count > 0) isTableRecord = true;
                }

                if (!isTableRecord)
                {
                    Log.Writter(string.Format("有附档格式配置，但附件没有需要导出的数据，不发送邮件"));
                    return;
                }

                if (this.附件HTML内容 && this.发邮件分组类型 == 0)
                {
                    this.MailBody = DbConn.DataTableToHTML(ds.Tables[0], this.MailBody);
                    this.是否发送邮件 = true;
                    return;
                }

                if (this.附件HTML内容 && this.发邮件分组类型 > 0)
                {
                    Log.Writter("开始生成分组类型的邮件内容");

                    mr = new MailArray(this.发邮件分组类型);
                    Log.Writter("初始化生成分组类");
                    mr.Mailgenerate(ds.Tables[0],this.MailSubject, this.MailBody);
                    Log.Writter("分组类内容生成完成");
                    this.是否发送邮件 = true;
                    return;
                }

                if ( !this.附件HTML内容 && this.发邮件分组类型 ==1)
                {
                    Log.Writter("开始生成分组类型的邮件内容");

                    mr = new MailArray(this.发邮件分组类型);
                    Log.Writter("初始化邮件地址");
                   
                    mr.MailAddressAnalyzing(ds.Tables[0], this.MailBody);
                    mr.MailCount = mr.MailTO.Count;
                    Log.Writter("初始化邮件地址完成");
                    this.是否发送邮件 = true;
                }

                attachExcel(ds, true);
                DbConn.CronHistoryRecord(conn, this.SN, this.attachMentFilename.ToString());
                this.是否发送邮件 = true;
            }

        }

        public void attachExcel(DataSet ds, bool hasTitle)
        {
            Log.Writter(string.Format("附件Excel生成准备中"));
            ExportFile.ExportFile epxls = new ExportFile.ExportFile($"{Dir.GetCurrentDirectory()}\\exceltmp", this.附件文件名, this.附件格式, this.文件名后缀);

            if (this.数据栏位格式化 != "")
                epxls.FormatColumnType(this.数据栏位格式化);

            for (int i = 0; i < ds.Tables.Count; i++)
            {
                if (ds.Tables[i].Rows.Count > 0)
                {
                    Log.Writter($"记录表名:{ds.Tables[i].TableName} 记录行数{ds.Tables[i].Rows.Count}");
                    epxls.Exportexcel(ds.Tables[i], true);
                }
            }
            this.attachMentFilename = epxls.SaveFile();
            Log.Writter(string.Format("附件Excel产生完成 {0}", this.attachMentFilename));
        }
    

        public void SwitchMailArray(int i)
        {
            if (this.mr.MailTO.Count > i) this.MailTO = this.mr.MailTO[i].ToString();
            if (this.mr.MailCC.Count > i) this.MailCC = this.mr.MailCC[i].ToString();
            if (this.mr.MailSubject.Count > i) this.MailSubject = this.mr.MailSubject[i].ToString();
            if (this.mr.MailBody.Count > i) this.MailBody = this.mr.MailBody[i].ToString();
            Log.Writter("设定分组发送邮件址完成");
        }

        public void TestSendMailSet()
        {
            this.MailTO = this.cmd.testToAddress;
            this.MailCC = null;
            this.MailBCC = null;
            if (!this.MailSubject.Contains("测试邮件"))
                this.MailSubject = "[测试邮件]" + this.MailSubject;

            Log.Writter("测试模式启动");
        }



    };

    public class MailArray
    {
        public int MailCount;
        public List<string> MailTO = new List<string>();
        public List<string> MailCC = new List<string>();
        public List<string> MailSubject = new List<string>();
        public List<string> MailBody = new List<string>();
        private int 发邮件分组类型; //0 常规发一封邮件 1 按单身MailTo栏位发送一封邮件 2.按单身MailTo栏位按邮件地址分组发送邮件
 
        public void MailAddressAnalyzing(DataTable dt,string subject)
        {
            if (dt.Columns.IndexOf("MailTO") == -1)
            {
                return;
            }
            int MailTOCol = dt.Columns.IndexOf("MailTO");
            int MailCCCol = dt.Columns.IndexOf("MailCC");
            int MailSubjectCol = dt.Columns.IndexOf("MailSubject");
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (MailTO.IndexOf(dt.Rows[i][MailTOCol].ToString()) != -1) continue;

                MailTO.Add(dt.Rows[i][MailTOCol].ToString());
                if (MailCCCol == -1)
                {
                    MailCC.Add("");
                }
                else
                {
                    MailCC.Add(dt.Rows[i][MailCCCol].ToString());
                }

                if (MailSubjectCol == -1)
                {
                    MailSubject.Add(subject);
                }
                else
                {
                    MailSubject.Add($"{subject}-{dt.Rows[i][MailSubjectCol].ToString()}");
                }
            }

            if (this.发邮件分组类型 == 1)
            {
                string s = string.Join(";", MailTO.ToArray());
                MailTO.Clear();
                MailTO.Add(s);

                string s1 = string.Join(";", MailCC.Distinct().ToArray());
                MailCC.Clear();
                MailCC.Add(s1);
            }

        }


        private void MailBodyAnalyzing(DataTable dt, string mailbody)
        {
            if (dt.Columns.IndexOf("MailTO") != -1)
            {
                dt.Columns.Remove("Mailto");
            }

            if (dt.Columns.IndexOf("MailCC") != -1)
            {
                dt.Columns.Remove("Mailcc");
            }

            StringBuilder sb = new StringBuilder();
            sb.AppendLine($"<html><body>{mailbody}<br><table  border=0 cellspacing=1 cellpadding=1 bgcolor=#0066FF>");

            sb.AppendLine("<tr bgcolor=#FFFFFF>");
            foreach (DataColumn col in dt.Columns)
            {
                sb.Append($"<td align=right nowrap=nowrap><center>{col.ColumnName.Trim()}</center></td>");
            }
            sb.Append("</tr>");

            foreach (DataRow row in dt.Rows)
            {
                sb.AppendLine("<tr bgcolor=#FFFFFF>");
                foreach (DataColumn col in dt.Columns)
                {
                    // Log.Writter(col.DataType.Name.ToString());
                    switch (col.DataType.Name)
                    {
                        case "Int32":
                            sb.Append($"<td align=right nowrap=nowrap>{row[col].ToString()}</td>");
                            break;
                        case "Int64":
                            sb.Append($"<td align=right nowrap=nowrap>{row[col].ToString()}</td>");
                            break;
                        case "Decimal":
                            sb.Append($"<td align=right nowrap=nowrap>{row[col].ToString()}</td>");
                            break;
                        case "Double":
                            sb.Append($"<td align=right nowrap=nowrap>{row[col].ToString()}</td>");
                            break;
                        case "DateTime":
                            sb.Append($"<td align=left nowrap=nowrap>{row[col].ToString()}</td>");
                            break;
                        case "Date":
                            sb.Append($"<td align=left nowrap=nowrap>{row[col].ToString()}</td>");
                            break;
                        default:
                            sb.Append($"<td nowrap=nowrap><center>{row[col].ToString()}</center></td>");
                            break;
                    }

                }
                sb.Append("</tr>");
            }

            sb.AppendLine("</table></body></html>");

            if (dt.Rows.Count > 0)
                this.MailBody.Add(sb.ToString());
        }

        #region DataTable筛选，排序返回符合条件行组成的新DataTable或直接用DefaultView按条件返回
        /// <summary>
        /// DataTable筛选，排序返回符合条件行组成的新DataTable
        ///或直接用DefaultView按条件返回
        /// eg:SortExprDataTable(dt,"Sex='男'","Time Desc",1)
        /// </summary>
        /// <param name="dt">传入的DataTable</param>
        /// <param name="strExpr">筛选条件</param>
        /// <param name="strSort">排序条件</param>
        /// <param name="mode">1,直接用DefaultView按条件返回,效率较高;
        /// 2,DataTable筛选，排序返回符合条件行组成的新DataTable</param>
        public static DataTable SortDataTable(DataTable dt, string strExpr, string strSort, int mode)
        {
            switch (mode)
            {
                case 1:
                    //方法一　直接用DefaultView按条件返回
                    dt.DefaultView.RowFilter = strExpr;
                    dt.DefaultView.Sort = strSort;
                    return dt;
                case 2:
                    //方法二　DataTable筛选，
                    //排序返回符合条件行组成的新DataTable
                    DataTable dt1 = new DataTable();
                    DataRow[] GetRows = dt.Select(strExpr, strSort);
                    //复制DataTable dt结构不包含数据
                    dt1 = dt.Clone();
                    foreach (DataRow row in GetRows)
                    {
                        dt1.Rows.Add(row.ItemArray);
                    }
                    return dt1;
                default:
                    return dt;
            }
        }
        #endregion

        public MailArray(int 发邮件分组类型)
        {
            this.发邮件分组类型 = 发邮件分组类型;
            this.MailCount = 0;
        }

        /// <summary>
        /// 生成邮件
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="subject"></param>
        /// <param name="mailbody"></param>
        public void Mailgenerate(DataTable dt, string subject,string mailbody)
        {            
            MailAddressAnalyzing(dt, subject);

            if (发邮件分组类型 == 1)
            {
                MailBodyAnalyzing(dt, mailbody);
            }
            else
            {
                foreach (var afilter in MailTO)
                {
                    MailBodyAnalyzing(SortDataTable(dt, $"MailTO='{afilter}'", "", 2), mailbody);
                }
            }
            this.MailCount = MailTO.Count;
        }
    }

    public static class DbConn
    {

        /// <summary>
        /// 取得需要连接数库的字符串
        /// </summary>
        /// <returns></returns>
        public static string GetDbConnectionString()
        {

            if (!File.Exists($"{Dir.GetCurrentDirectory()}\\config.xml"))
            {
                Log.Writter("配制文件不存在");
                return null;
            }

            string connstr = null;
            XDocument xd = XDocument.Load($"{Dir.GetCurrentDirectory()}\\config.xml");
            foreach (XElement item in xd.Root.Descendants("conndb"))
            {
                connstr = item.Element("connstring").Value;

            }
            xd = null;


            if (connstr == null)
            {
                Log.Writter("数据库连接字口串没有设写好,请先设写连接");
                return null;
            }

            Log.Writter("读取连接字符串完成");
            return connstr;
        }

        /// <summary>
        /// 取得一个数据连接，并打开这个连接
        /// </summary>
        /// <returns></returns>
        public static SqlConnection GetDbConnection()
        {
            string connstr = GetDbConnectionString();
            if (connstr == null)
            {
                Log.Writter("数据库连接字口串没有设写好,请先设写连接");
                return null;
            }

            try
            {
                SqlConnection conn = new SqlConnection(connstr);
                conn.Open();
                return conn;
            }
            catch (Exception e)
            {
                Log.Writter("数据库连接失败" + e.Message);
                return null;
            }
        }



        /// <summary>
        /// 取得任务的主要参数 如邮件地址,文件名格式.
        /// </summary>
        /// <param name="conn">SQL连接</param>
        /// <param name="cronid">任务ID</param>
        /// <returns></returns>       
        public static CronStruct GetCron(SqlConnection conn, string cronid)
        {
            SqlCommand cmd = new SqlCommand("select * from dbo.crontab where SN=@sn", conn);
            cmd.Parameters.AddWithValue("@sn", cronid);

            SqlDataReader dr = cmd.ExecuteReader();

            CronStruct cs = new CronStruct();


            if (dr.HasRows)
            {
                dr.Read();
                cs.MailTO = dr["MailTO"].ToString();
                cs.MailCC = dr["MailCC"].ToString();
                cs.MailBCC = dr["MailBCC"].ToString();
                cs.MailSubject = dr["MailSubject"].ToString();
                cs.MailBody = dr["MailBody"].ToString();
                cs.附件文件名 = dr["附件文件名"].ToString();
                cs.附件格式 = dr["附件格式"].ToString();
                cs.文件名后缀 = dr["文件名后缀"].ToString();
                cs.CronName = dr["排程名称"].ToString();
                cs.数据栏位格式化 = dr["数据栏位格式化"].ToString();

                cs.SN = dr["SN"].ToString();
                cs.执行命令 = dr["执行命令"].ToString();

                if (dr["邮件发送失败重试"].ToString() == "") cs.邮件发送失败重试 = false;
                else
                    cs.邮件发送失败重试 = Convert.ToBoolean(dr["邮件发送失败重试"].ToString());

                cs.重试间隔分钟 = dr["重试间隔分钟"].ToString() == "" ? 0 : Convert.ToInt32(dr["重试间隔分钟"].ToString());
                cs.失败重试次数 = dr["失败重试次数"].ToString() == "" ? 0 : Convert.ToInt32(dr["失败重试次数"].ToString());

                if (dr["附件HTML内容"].ToString() == "") cs.附件HTML内容 = false;
                else
                    cs.附件HTML内容 = Convert.ToBoolean(dr["附件HTML内容"].ToString());

                cs.发邮件分组类型 = dr["发送邮件类型"].ToString() == "" ? 0 : Convert.ToInt32(dr["发送邮件类型"].ToString());

                if (dr["发送钉钉消息"].ToString() == "") cs.发送钉钉消息 = false;
                else
                    cs.发送钉钉消息 = Convert.ToBoolean(dr["发送钉钉消息"].ToString());

                cs.钉钉消息地址 = dr["钉钉消息地址"].ToString();

                return cs;
            }
            else
            {
                return null;
            }

        }


        /// <summary>
        /// 任务执行成功后，回写任务完成时间的记录到数据库.
        /// </summary>
        /// <param name="conn">SQL连接</param>
        /// <param name="cronid">任务ID</param>
        /// <returns></returns>
        public static bool CronStateUpdae(SqlConnection conn, string cronid)
        {
            SqlCommand cmd = new SqlCommand("update crontab set 最后执行时间=getdate() where SN=@sn", conn);
            cmd.Parameters.AddWithValue("@sn", cronid);
            if (cmd.ExecuteNonQuery() > 0)
            {
                Log.Writter("任务执行状态回写数据库完成");
                return true;
            }
            else
            {
                Log.Writter("数据库失败");
                return false;
            }
        }

        /// <summary>
        /// 取得发送历史记录的附件名
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="cronid"></param>
        /// <param name="SemdRecordTime"></param>
        /// <returns></returns>
        public static string GetCronHistoryRecord(SqlConnection conn, string cronid, string HistoryRedordId)
        {
            SqlCommand cmd = new SqlCommand("select * from dbo.cronhistory where SN=@sn and ID=@ID", conn);
            cmd.Parameters.AddWithValue("@sn", cronid);
            cmd.Parameters.AddWithValue("@ID", HistoryRedordId);

            SqlDataReader dr = cmd.ExecuteReader();
            if (dr.HasRows)
            {
                dr.Read();
                return dr["附件"].ToString();
            }
            else
            {
                return null;
            }

        }

        /// <summary>
        /// 任务附件产生完成后,记录下来.
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="cronid"></param>
        /// <param name="attachMentFilename"></param>
        /// <returns></returns>
        public static bool CronHistoryRecord(SqlConnection conn, string cronid, string attachMentFilename)
        {
            SqlCommand cmd = new SqlCommand($"insert cronhistory (SN,附件) values ('{cronid}','{attachMentFilename}')", conn);
            if (cmd.ExecuteNonQuery() > 0)
            {
                Log.Writter("任务执行产生附档后,记录历史发送表");
                return true;
            }
            else
            {
                Log.Writter("任务执行产生附档后,历史记录失败");
                return false;
            }
        }

        public static bool CronHistoryStateUpdate(SqlConnection conn, string cronid, bool state)
        {
            string str = state ? "发送完成" : "发送失败";
            SqlCommand cmd = new SqlCommand($"update cronhistory set 状态='{str}' where SN=@sn", conn);
            cmd.Parameters.AddWithValue("@sn", cronid);
            if (cmd.ExecuteNonQuery() > 0)
            {
                Log.Writter("任务执行产生附档后,更新历史记录历史发送表");
                return true;
            }
            else
            {
                Log.Writter("任务执行产生附档后,历史记录失败");
                return false;
            }
        }


        /// <summary>
        /// 取得任务需要生成附件的数据集
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="cronid"></param>
        /// <param name="SheetName"></param>
        /// <returns></returns>
        public static DataSet GetAttachmentData(SqlConnection conn, string cronid, bool SheetName)
        {
            SqlCommand cmd = new SqlCommand("select * from cronExportFile where SN=@sn", conn);
            cmd.Parameters.AddWithValue("@sn", cronid);
            try
            {
                SqlDataAdapter sda1 = new SqlDataAdapter(cmd);
                DataTable d1 = new DataTable();
                sda1.Fill(d1);

                DataSet ds = new DataSet();

                List<string> para = new List<string>();

                foreach (DataRow row in d1.Rows)
                {
                    para.Clear();
                    string sqlprocedure = row["存储过程"].ToString();
                    if (row["参数1"].ToString() != "")
                    {
                        string paratmp = GetParameter(conn, row["参数1"].ToString());
                        if (paratmp != null) para.Add(paratmp);
                    }

                    if (row["参数2"].ToString() != "")
                    {
                        string paratmp = GetParameter(conn, row["参数2"].ToString());
                        if (paratmp != null) para.Add(paratmp);
                    }

                    if (row["参数3"].ToString() != "")
                    {
                        string paratmp = GetParameter(conn, row["参数3"].ToString());
                        if (paratmp != null) para.Add(paratmp);
                    }

                    if (row["参数4"].ToString() != "")
                    {
                        string paratmp = GetParameter(conn, row["参数4"].ToString());
                        if (paratmp != null) para.Add(paratmp);
                    }

                    if (row["参数5"].ToString() != "")
                    {
                        string paratmp = GetParameter(conn, row["参数5"].ToString());
                        if (paratmp != null) para.Add(paratmp);
                    }

                    if (para.Count > 0)
                        sqlprocedure = sqlprocedure + " " + string.Join(",", para.Select(r => "'" + r + "'"));

                    Log.Writter(string.Format("存储过程 {0}", sqlprocedure));

                    SqlCommand cmd1 = new SqlCommand(sqlprocedure, conn);
                    // cmd1.CommandType = CommandType.StoredProcedure;

                    SqlDataAdapter sda = new SqlDataAdapter(cmd1);

                    if (SheetName)
                    {
                        sda.Fill(ds, row["SheetName"].ToString());
                    }
                    else
                    {
                        sda.Fill(ds);
                    }
                }

                return ds;
            }
            catch (Exception e)
            {
                Log.Writter("附件数据集收集有问题" + e.Message);
                return null;
            }

        }


        /// <summary>
        /// 取得需要生成附件的数据集,不定义表的名称
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="cronid"></param>
        /// <returns></returns>
        public static DataSet GetAttachmentData(SqlConnection conn, string cronid)
        {
            return GetAttachmentData(conn, cronid, false);

        }


        /// <summary>
        /// 解析执行存储过程的参数值
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="sqlstr"></param>
        /// <returns></returns>
        public static string GetParameter(SqlConnection conn, string sqlstr)
        {
            if (!sqlstr.ToUpper().Contains("SELECT"))
            {
                return sqlstr.Trim();
            }

            SqlCommand cmd = new SqlCommand(sqlstr, conn);
            try
            {
                return cmd.ExecuteScalar().ToString();

            }
            catch (Exception ex)
            {
                Log.Writter(ex.Message);
                return null;
            }

        }

        /// <summary>
        /// 检查是否有设定附件
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="cronid"></param>
        /// <returns>true</returns>
        public static bool CheckAttachmentData(SqlConnection conn, string cronid)
        {
            SqlCommand cmd = new SqlCommand("select count(*) count from dbo.cronExportFile where SN=@sn", conn);
            cmd.Parameters.AddWithValue("@sn", cronid);

            try
            {
                if (Convert.ToInt32(cmd.ExecuteScalar()) > 0)
                    return true;
                else return false;
            }
            catch (Exception ex)
            {
                Log.Writter(ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 数据表DataTable 转 HTML
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string DataTableToHTML(DataTable dt)
        {
            return DataTableToHTML(dt, string.Empty);
        }
        /// <summary>
        /// 数据表DataTable 转 HTML
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="mailbody"></param>
        /// <returns></returns>
        public static string DataTableToHTML(DataTable dt, string mailbody)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine($"<html><body>{mailbody}<br><table  border=0 cellspacing=1 cellpadding=1 bgcolor=#0066FF>");

            sb.AppendLine("<tr bgcolor=#FFFFFF>");
            foreach (DataColumn col in dt.Columns)
            {
                sb.Append($"<td align=right nowrap=nowrap><center>{col.ColumnName.Trim()}</center></td>");
            }
            sb.Append("</tr>");

            foreach (DataRow row in dt.Rows)
            {
                sb.AppendLine("<tr bgcolor=#FFFFFF>");
                foreach (DataColumn col in dt.Columns)
                {
                    // Log.Writter(col.DataType.Name.ToString());
                    switch (col.DataType.Name)
                    {
                        case "Int32":
                            sb.Append($"<td align=right nowrap=nowrap>{row[col].ToString()}</td>");
                            break;
                        case "Int64":
                            sb.Append($"<td align=right nowrap=nowrap>{row[col].ToString()}</td>");
                            break;
                        case "Decimal":
                            sb.Append($"<td align=right nowrap=nowrap>{row[col].ToString()}</td>");
                            break;
                        case "Double":
                            sb.Append($"<td align=right nowrap=nowrap>{row[col].ToString()}</td>");
                            break;
                        case "DateTime":
                            sb.Append($"<td align=left nowrap=nowrap>{row[col].ToString()}</td>");
                            break;
                        case "Date":
                            sb.Append($"<td align=left nowrap=nowrap>{row[col].ToString()}</td>");
                            break;
                        default:
                            sb.Append($"<td nowrap=nowrap><center>{row[col].ToString()}</center></td>");
                            break;
                    }

                }
                sb.Append("</tr>");
            }

            sb.AppendLine("</table></body></html>");
            return sb.ToString();
        }
    }


}
